#include <stdlib.h>
#include <stdio.h>
#include <sys/dispatch.h>
#include <errno.h>
#include <process.h>

#define ATTACH_POINT "EZParkService"

typedef struct _pulse msg_header_t;
typedef struct _my_data {
    msg_header_t hdr;
    int data;
} my_data_t;


int func_Simulator();
int func_EZPark();

int main(int argc, char *argv[]) {
	pid_t PID_sim=0, PID_ezpark=0;
	int ret;

	printf("EZPark MASTER template....\n");

	//Create EZPark process
	PID_ezpark = fork();
	if (0 == PID_ezpark)
	{
		//execute EZPark program
		ret = func_EZPark();
		exit(ret);
	}

	//Create Simulator process
	PID_sim = fork ();
	if (0 == PID_sim)
	{
		ret = func_Simulator(PID_ezpark);
		exit(ret);
	}

	wait (NULL);
	wait (NULL);

	return EXIT_SUCCESS;
}

int func_Simulator()
{
    my_data_t msg;
    int server_coid;
	int ret=EXIT_SUCCESS;

	printf ("[CLI]func_Simulator: ()\n");

    if (-1 == (server_coid = name_open(ATTACH_POINT, 0)))
    {
    	printf ("[CLI]func_Simulator: name_open error\n");
        return EXIT_FAILURE;
    }

    /* We would have pre-defined data to stuff here */
    msg.hdr.type = 0x00;
    msg.hdr.subtype = 0x00;

    /* Do whatever work you wanted with server connection */
    for (msg.data=0; msg.data < 5; msg.data++)
    {
    	printf ("[CLI]func_Simulator: Client sending %d \n", msg.data);
        if (-1 == MsgSend(server_coid, &msg, sizeof(msg), NULL, 0))
        {
        	printf ("[CLI]func_Simulator: MsgSend %d ERROR \n", msg.data);
        	ret = EXIT_FAILURE;
            break;
        }
    }

    /* Close the connection */
    name_close(server_coid);

	printf ("[CLI]func_Simulator: RETURN\n");
	return ret;
}

int func_EZPark()
{
	name_attach_t *attach;
	int rcvid, ret=EXIT_SUCCESS;
	my_data_t msg;

	printf ("[SRV]func_EZPark():%d\n", getpid());

	if (NULL == (attach = name_attach(NULL, ATTACH_POINT, 0)))
	{
		return EXIT_FAILURE;
	}

	while (1)
	{
		rcvid = MsgReceive(attach->chid, &msg, sizeof(msg), NULL);
		if (-1 == rcvid )
		{/* Error condition, exit */
			ret = EXIT_FAILURE;
			break;
		}

		if (0 == rcvid)
		{// pulse received
			printf ("[SRV]func_EZPark(): pulse %d\n", msg.hdr.code);
			if (_PULSE_CODE_DISCONNECT == msg.hdr.code)
				break;
			continue;
		}

		/* name_open() sends a connect message, must EOK this */
		if (_IO_CONNECT  == msg.hdr.type)
		{
			printf ("[SRV]func_EZPark(): msg.hdr.type %d [_IO_CONNECT]\n", msg.hdr.type);
			MsgReply( rcvid, EOK, NULL, 0 );
			continue;
		}

	    /* Some other QNX IO message was received; reject it */
	    if (msg.hdr.type > _IO_BASE && msg.hdr.type <= _IO_MAX )
	    {
			printf ("[SRV]func_EZPark(): msg.hdr.type %d [other QNX IO message]\n", msg.hdr.type);
	        MsgError( rcvid, ENOSYS );
			continue;
	    }

	    /* A message (presumable ours) received, handle */
	    printf ("[SRV]func_EZPark(): msg.hdr.type %d [data = %d]\n", msg.hdr.type, msg.data);
	    MsgReply(rcvid, EOK, 0, 0);
	    //break;
	}

    /* Remove the name from the space */
    name_detach(attach, 0);

	printf ("[SRV]func_EZPark(): RETURN\n");
	return ret;
}
